<?php 

/**
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with the Zend Framework source files
* It is available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so they can send you a copy immediately.
*
* @package    Zend_Pdf
* @author     Martijn Korse (http://devshed.excudo.net)
* @license    http://framework.zend.com/license/new-bsd     New BSD License
*/

/**
* The source shown here contains the code of 3 classes.
* If you download the zip file, the source of these 3 classes will be split into three seperate files
*
* Please note that this code will only work with ZF >= 1.7
* If you are using a version < 1.7, please go to
*   http://devshed.excudo.net/scripts/php/explanation/excudo+pdf+textblock
* For instructions
*/

/** Excudo_Pdf_Textblock.php */

/**
* PDF Textblock
*
* A class that can handle big strings and output them like a textblock consisting of multiple lines with custom alignment
*
* @package    Zend_Pdf
* @license    http://framework.zend.com/license/new-bsd     New BSD License
* @version    2.0
*/
class Excudo_Pdf_Textblock
{
   /**
    * Some constants of possible alignment values
    */
   const ALIGN_LEFT   = 'left';
   const ALIGN_RIGHT   = 'right';
   const ALIGN_CENTER   = 'center';
   const ALIGN_JUSTIFY   = 'justify';

   /**
    * @var Zend_Pdf_Resource_Font
    */
   protected $_font;

   /**
    * The fontsize we have to work with in this textblock
    *
    * @var Float
    */
   protected $_fontsize;

   /**
    * The total width of the string that we have to convert into multiple lines (if necessary)
    *
    * @var Float
    */   
   protected $_totalWidth = 0;
   /**
    * The (maximum) width we want 1 line to have
    *
    * @var Float
    */
   protected $_lineWidth = 0;
   /**
    * The total height of all the lines of this textblock together
    * This is the sum of the height of all the lines + the gap between them
    *
    * @var Float
    */
   protected $_totalHeight = 0;
   /**
    * The height of 1 line
    * This is calculated based on the font passed to the constructor
    *
    * @var Float
    */
   protected $_lineHeight = 0;
   /**
    * The height of the gap between the individual lines
    * This is calculated based on the font passed to the constructor
    *
    * @var Float
    */
   protected $_lineGap = 0;

   /**
    * The width we want this block to have
    *
    * @var Float
    */
   protected $_blockWidth = 0;

   /**
    * Alignment of this textblock
    *
    * setting default to Left
    */
   protected $_align = self::ALIGN_LEFT;

   /**
    * Array that will hold all the individual lines
    */   
   protected $_lines = array();
   /**
    * Array that will hold all the widths of the lines in $this->_lines,
    * using the same indexes
    */
   protected $_lineWidths = array();

   /**
    *
    * Constructor
    *
    * @param Zend_Pdf_Resource_Font $font
    * @param Float $fontSize
    */

   public function __construct(Zend_Pdf_Resource_Font $font, $fontsize, $blockWidth = 0)
   {
      $this->_font = $font;
      $this->_fontsize = $fontsize;
      $this->_lineHeight = ($font->getLineHeight()  / $font->getUnitsPerEm()) * $fontsize;
      $this->_lineGap = ($font->getLineGap()  / $font->getUnitsPerEm()) * $fontsize;
      // if a width is passed, we set it
      if ($blockWidth > 0)
      {
         $this->setBlockWidth($blockWidth);
      }
   }

   /**
    * Parses a string and returns the total width
    *
    * If font and fontsize are not set, the ones passed to the constructor are used
    *
    * Credits for this calculation go to Willie Alberty:
    * http://framework.zend.com/issues/browse/ZF-313
    *
    * @param String $string
    * @param Zend_Pdf_Resource_Font $font (optional)
    * @param Float $fontSize (optional)
    *
    * @return Float;
    */
   function parseString($string, $font=null, $fontsize=null)
   {
      if (is_null($font))
         $font = $this->_font;
      if (is_null($fontsize))
         $fontsize = $this->_fontsize;

      $drawingString = iconv('', 'UTF-16BE', $string);
      $characters = array();
      for ($i = 0; $i < strlen($drawingString); $i++) {
         $characters[] = (ord($drawingString[$i++]) << 8) | ord($drawingString[$i]);
      }
      $glyphs = $font->glyphNumbersForCharacters($characters);
      $widths = $font->widthsForGlyphs($glyphs);
      $stringWidth = (array_sum($widths) / $font->getUnitsPerEm()) * $fontsize;
      return $stringWidth;
    }
   
   /**
    * Creates an array of lines based on one line
    * This array can later be used to create a textblock of individual lines
    *
    * This method doesn't return anything, but saves the lines in the _lines array
    * Use the public drawText() to output the lines.
    *
    * @param String $string
    * @param Float   $maxWidth
    *
    * @return Void
    *
    * @todo handle whitespaces better (currently any whitespace is handles as 1 space)
    * @todo handle words that are too long to fit in the textblock
    */
   function createBlock($string, $maxWidth = null)
   {
      if (!is_null($maxWidth))
      {
         $this->setBlockWidth($maxWidth);
      }
      
      $this->_lines = array();
      // exploding on newlines so we get an array of paragraphs
      $paragraphs = preg_split('/\r\n|\r|\n/', $string);
      foreach ($paragraphs AS $paragraph)
      {
         if (!empty($paragraph))
         {
            // explode on whitespaces so we get individual words
            // TODO: fix tabs, multiple spaces
            $words = preg_split('/\s+/', $paragraph);
            $tempLine = '';
            $lastLine = '';
            foreach ($words AS $word)
            {
               $lastLine = $tempLine;
               $tempLine .= $tempLine != '' ? ' '.$word : $word;
               if ($this->parseString($tempLine) > $maxWidth)
               {
                  if ($lastLine == '')
                  {
                     // TODO: we have to break up the word
                  }
                  else
                  {
                     $this->addLine($lastLine, null, False);
                     $tempLine = $word;
                  }
               }
            }
            $this->addLine($tempLine);
         }
         else
         {
            $this->addLine('');
         }
      }
   }

   /**
    * uses an Excudo_Pdf_Page object to output
    *
    * @param Zend_Pdf_Page $page
    * @param Float $x
    * @param Float $y
    *
    * @return Float the totalheight of the textblock that was outputted
    */
   public function drawText(Excudo_Pdf_Page &$page, $x, $y)
   {
      $xPos = $x;
      $yPos = $y;
      foreach ($this->_lines AS $i => $line)
      {
         // word space adjustment
         $wsa = False;

         if ($this->_align == self::ALIGN_RIGHT)
         {
            $xPos = $x + ($this->_blockWidth - $line['width']);
         }
         elseif ($this->_align == self::ALIGN_CENTER)
         {
            $xPos = ( ($x + ($this->_blockWidth - $line['width'])) + $x ) / 2;
         }
         elseif ($this->_align == self::ALIGN_JUSTIFY)
         {
            $wordCount = count(preg_split('/\s+/', $line['text']));
            if ($wordCount > 1 && !$line['lastInParagraph'])
               $wsa = ($this->_blockWidth - $line['width']) / ($wordCount - 1);
         }
         if ($this->_align == self::ALIGN_JUSTIFY)
            $page->drawTextBlock($line['text'], $xPos, $yPos, null, $wsa);
         else
            $page->drawText($line['text'], $xPos, $yPos);
         $yPos -= ($this->_lineHeight + $this->_lineGap);
      }
      return $this->_totalHeight;
   }

   /**
    * Adds a line to the internal array of lines
    * If the width is not passed, it will be calculated
    *
    * @param String $string Line of text
    * @param Float $width the width of this line (in case you know it at the time of passing)
    * @param Boolean $lastInParagraph. When true, the width of this line is recorded
    */
   protected function addLine($string, $width = null, $lastInParagraph = True)
   {
      if (is_null($width))
      {
         $width = $this->parseString($string);
      }
      $this->_lines[] = array(
         'text'         => $string,
         'width'         => $width,
         'lastInParagraph'   => $lastInParagraph
         );
      $this->_totalHeight += $this->_lineHeight + $this->_lineGap;
   }

   /**
    * sets (and checks) the alignment of the textblock
    *
    * @param $align has to be a constant of this class, indicating the alignment
    */
   public function setAlignment($align)
   {
      if (!in_array($align, array(self::ALIGN_LEFT, self::ALIGN_RIGHT, self::ALIGN_CENTER, self::ALIGN_JUSTIFY)))
      {
         throw new Exception('this is not a valid alignment value');
      }
      else
      {
         $this->_align = $align;
      }
   }
   /**
    * setter for the width of the textblock
    * whatever is passed will be converted to a float without checking
    *
    * @param $width
    */
   public function setBlockWidth($width)
   {
      $this->_blockWidth = (float) $width;
   }
   /**
    * getter for the blockWidth
    *
    * @return Float
    */
   public function getBlockWidth()
   {
      if (False === 0)
         throw new Exception('Textblock width not set');
      else
         return $this->_blockWidth;
   }
}

/** Excudo_Pdf.php */

#require_once 'Excudo_Pdf_Page.php';

/**
* Excudo PDF
*
* Extension of Zend PDF.
* The only difference is that the method newPage creates and instance of Excudo_Pdf_Page instead of Zend_Pdf_Page.
*
* @package    Zend_Pdf
* @license    http://framework.zend.com/license/new-bsd     New BSD License
*/
class Excudo_Pdf extends Zend_Pdf
{
   public function newPage($param1, $param2 = null)
   {
      if ($param2 === null) {
         return new Excudo_Pdf_Page($param1, $this->_objFactory);
      } else {
         return new Excudo_Pdf_Page($param1, $param2, $this->_objFactory);
      }
   }   
}


/** Excudo_Pdf_Page.php */

/**
* Excudo PDF Page
*
* Extension of Zend Pdf Page.
* Has 1 extra method which can create text-blocks
*
* @package    Zend_Pdf
* @license    http://framework.zend.com/license/new-bsd     New BSD License
*/
class Excudo_Pdf_Page extends Zend_Pdf_Page
{
   public function drawTextBlock($text, $x, $y, $charEncoding = '', $wordSpaceAdjust=False)
   {
      if ($this->_font === null) {
         throw new Zend_Pdf_Exception('Font has not been set');
      }

      $this->_addProcSet('Text');

      $textObj = new Zend_Pdf_Element_String($this->_font->encodeString($text, $charEncoding));
      $xObj   = new Zend_Pdf_Element_Numeric($x);
      $yObj   = new Zend_Pdf_Element_Numeric($y);

      $this->_contents .= "BT";
      if (False !== $wordSpaceAdjust)
      {
         $this->_contents .= sprintf(" %.3f Tw", $wordSpaceAdjust);
      }
      $this->_contents .= "\n"
                .  $xObj->toString() . ' ' . $yObj->toString() . " Td\n"
                .  $textObj->toString() . " Tj\n"
                .  "ET\n";
   }
}

/**
 * Zawin tekst po określonej długości znaków.
 * 
 * @param Zend_Pdf_Page $page
 * @param string $text
 * @param int $x
 * @param int $y
 * @param int $width
 * @param string $brake
 * @param bool $cut
 * @return void
 */
function drawTextWrap($page, $text, $x, $y, $width, $brake = "\n", $cut = true)
{
	// przygotuj tekst
	$text = wordwrap($text, $width, $brake, $cut);
	$token = strtok($text, $brake);

	$fontSize = $page->getStyle()->getFontSize();

	// rysuje każdą linię tekstu niżej od poprzedniej 
	// o wysokośc (wielkość) czcionki
	while (false !== $token) 
	{
		$y -= $fontSize;
		
		$page->drawText($token, $x, $y, 'UTF-8');

		$token = strtok("\n");
	};
}

$types = array('big', 'medium2', 'medium1', 'small');

$pdf = new Excudo_Pdf();

	// Styl tytułu
	$styleTitle  = new Zend_Pdf_Style();
		$font    = Zend_Pdf_Font::fontWithName(Zend_Pdf_Font::FONT_HELVETICA_BOLD);
		$color   = Zend_Pdf_Color_Html::namedColor('black');
	
	$styleTitle->setFont($font, 40);
	$styleTitle->setFillColor($color);
	
	// Styl pod tytulu
	$styleSubTitle  = new Zend_Pdf_Style();
		$font1    = Zend_Pdf_Font::fontWithName(Zend_Pdf_Font::FONT_HELVETICA);
		$color   = Zend_Pdf_Color_Html::color('#222222');
	
	$styleSubTitle->setFont($font1, 14);
	$styleSubTitle->setFillColor($color);
	
	// Styl nagłówka
	$styleHeader = new Zend_Pdf_Style();
		$font    = Zend_Pdf_Font::fontWithName(Zend_Pdf_Font::FONT_HELVETICA_BOLD);
		$color   = Zend_Pdf_Color_Html::namedColor('black');
	
	$styleHeader->setFont($font, 16);
	$styleHeader->setFillColor($color);
	
	// Styl opisu
	$styleDesc = new Zend_Pdf_Style();
		$font    = Zend_Pdf_Font::fontWithName(Zend_Pdf_Font::FONT_HELVETICA_ITALIC);
		$color   = Zend_Pdf_Color_Html::color('#444444');
	
	$styleDesc->setFont($font, 13);
	$styleDesc->setFillColor($color); 
	
	// styl kodu
	$styleCode = new Zend_Pdf_Style();
		$font  = Zend_Pdf_Font::fontWithName(Zend_Pdf_Font::FONT_COURIER);
		$color = Zend_Pdf_Color_Html::color('#666666');
	
	$styleCode->setFont($font, 10);
	$styleCode->setFillColor($color);


/* @var Zend_Pdf_Page */
//$page = new Excudo_Pdf_Page(Zend_Pdf_Page::SIZE_A4);
$page = $pdf->newPage(Zend_Pdf_Page::SIZE_A4); // 595:842
$pdf->pages[] = $page;


	// Budowanie nagłówka
	$page->setStyle($styleTitle);
	$page->drawText("Certyfikat", 200, 760);
	
	// Grafika certyfikatu
	$path = sprintf('%s/certyfikaty/%s/%s.png', PUBLIC_PATHNAME, CATALOG_TYPE, 'big');
	$image = Zend_Pdf_Image::imageWithPath($path);

		// obliczanie wyśrodkowanego położenia
		$x1 = (595 - $image->getPixelWidth()) / 2;
		$y1 = 300;
		$x2 = $image->getPixelWidth();
		$y2 = $image->getPixelHeight();

	$page->drawImage($image, $x1, $y1, $x2 + $x1, $y2 + $y1);

	// Pisanie tekstu
	$page->setStyle($styleSubTitle);
	$line1 = 'Redakcja infoportalu ' . CATALOG_HOSTNAME;
	$line2 = 'na podstawie opinii przekazanych przez klientów';
	$line3 = 'rekomenduje usługi gabinetu:';
	$line4 = $this->row['name'];
	
//	$page->dr
	
//	$page->drawTextBlock($line1, 10, 500, 'UTF-8', 10);
//	$page->drawTextBlock($line1, 10, 520, 'UTF-8', 1);
//	$page->drawTextBlock($line1, 10, 540, 'UTF-8', 40);
//Zend_Pdf_Resource_Font::
//	drawTextCenter($page, $line1, 300, 500);
//	drawTextCenter($page, $line2, 280, 500);
//	drawTextCenter($page, $line3, 260, 500);
//	drawTextCenter($page, $line4, 240, 500);	

$eptb = new Excudo_Pdf_Textblock($font1, 18);
$eptb->setAlignment(Excudo_Pdf_Textblock::ALIGN_CENTER);

// outputing, and saving height
$eptb->createBlock($line1, $page->getWidth());
$height = $eptb->drawText($page, 0, 250);

$eptb->createBlock($line2, $page->getWidth());
$height = $eptb->drawText($page, 0, 230);

$eptb->createBlock($line3, $page->getWidth());
$height = $eptb->drawText($page, 0, 210);

$eptb->createBlock($line4, $page->getWidth());
$height = $eptb->drawText($page, 0, 190);

print $pdf->render();

function drawTextCenter($page, $text, $y, $width)
{
	$pageWidth  = $page->getWidth();
	$fontSize   = $page->getStyle()->getFontSize();
	
	$font = $page->getStyle()->getFont();
	
	$ascent = $font->getAscent();
	$descent = $font->getDescent();
	$lineGap = $font->getLineGap();
	
//	Zend_Registry::get('logger')->log("getAscent: $ascent", Zend_Log::DEBUG);
//	Zend_Registry::get('logger')->log("getDescent: $descent", Zend_Log::DEBUG);
//	Zend_Registry::get('logger')->log("getLineGap: $lineGap", Zend_Log::DEBUG);

//	Zend_Registry::get('logger')->log($font->widthsForGlyphs('a'), Zend_Log::DEBUG);
//	Zend_Registry::get('logger')->log($font->widthsForGlyphs($text), Zend_Log::DEBUG);
	
	$textLength = strlen($text);
	$textWidth = $fontSize*$textLength;
	
//	$x = $pageWidth > $textWidth
//			? ($pageWidth-$textWidth)/2
//			: 0;
 
//	$x = $width > $textLength ? $width - $textLength : 0;
	
//	$text = str_repeat(' ', $x) . $text;
			
//	Zend_Registry::get('logger')->log("pageWidth: $pageWidth", Zend_Log::DEBUG);
//	Zend_Registry::get('logger')->log("fontSize: $fontSize", Zend_Log::DEBUG);
//	Zend_Registry::get('logger')->log("textLength: $textLength", Zend_Log::DEBUG);
//	Zend_Registry::get('logger')->log("textWidth: $textWidth", Zend_Log::DEBUG);
//	Zend_Registry::get('logger')->log("x: $x", Zend_Log::DEBUG);
	
	$page->drawText($text, 10, $y);
}